package com.akuhome.resource.service;

import com.akuhome.resource.DO.check.AccCheck;
import com.akuhome.resource.DO.check.ClassroomCheck;
import com.akuhome.resource.DO.report.*;
import com.akuhome.resource.dao.CheckDao;
import com.akuhome.resource.dao.ReportDao;
import com.akuhome.resource.dto.report.YearTrainInfo;
import com.akuhome.resource.entity.Part;
import com.akuhome.resource.entity.Project;
import com.akuhome.resource.enums.ResultEnum;
import com.akuhome.resource.exception.ResourceException;
import com.akuhome.resource.service.entity.PartService;
import com.akuhome.resource.service.entity.ProjectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class ReportService {
    @Autowired
    ReportDao reportDao;
    @Autowired
    ProjectService projectService;
    @Autowired
    CheckDao checkDao;
    @Autowired
    PartService partService;
    //uid:usage
    Map<String,UsageInfo> usageMap;

    //生成上个月的报表
    @Transactional
    public void initMonthReport(){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH,-1);
        Date tarDate = calendar.getTime();
//        System.out.println(tarDate);
        MonthReport monthReport = new MonthReport();
        monthReport.setDate(tarDate);
        insertMonthReport(monthReport);
    }
    //生成去年的报表
    @Transactional
    public void initYearReport(){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR,-1);
        Date tarDate = calendar.getTime();
//        System.out.println(tarDate);
        YearReport yearReport = new YearReport();
        yearReport.setDate(tarDate);
        insertYearMonthReport(yearReport);
    }
    //获取月度部门统计
    public List<DepartmentStatistic> findAllDepStaByDateMonth(Date date){
        return reportDao.findAllDepartmentStatisticByDateMonth(date);
    }

    public List<TrainStatistic> findAllTrainStatisticByPartAndMonthReportId
            (String part, Integer monthReportId){
        return reportDao.findAllTrainStatisticByPartAndMonthReportId(part,monthReportId);
    }

    public List<TrainStatistic> findAllTrainStatisticByMonthReportId
            (Integer monthReportId){
        return reportDao.findAllTrainStatisticByMonthReportId(monthReportId);
    }

    public Date findDateByMonthReportId(Integer id){
        return reportDao.findDateByMonthReportId(id);
    }

    public List<MonthReportStatistic> findAllMonStaByDateYear(Date date){
        return reportDao.findAllMonthReportStatisticByDateYear(date);
    }

    public YearTrainInfo findYearTrainInfoByPartAndYearReportId
        (String part,Integer yearReportId){
        YearTrainInfo yearTrainInfo = new YearTrainInfo();
        yearTrainInfo.setYear(reportDao.findYearByYearReportId(yearReportId));
        yearTrainInfo.setInfoList(reportDao.findDepartmentStatisticInfoByYearReportIdAndPart(part,yearReportId));
        return yearTrainInfo;
//        return reportDao.findYearTrainInfoByPartAndYearReportId(part,yearReportId);
    }

    public void insertMonthReport(MonthReport monthReport){
        //插入基本数据
        reportDao.insertMonthReport(monthReport);
        List<Project> projectList = projectService.findAllProjectInMonth(monthReport.getDate());
        //根据project初始化usageMap
        initUsageMap(projectList);
        //将projectList转换为培训统计
        List<TrainStatistic> trainStatisticList = projectToTrainStatistic(projectList,monthReport.getId());
        //生成部门统计
        List<DepartmentStatistic> departmentStatisticList = trainToDepart(trainStatisticList,monthReport.getId());
        //插入数据库
        if(departmentStatisticList.size() > 0)
            reportDao.insertDepartmentStatistic(departmentStatisticList);
        reportDao.insertTrainStatistic(trainStatisticList);
    }

    public void insertYearMonthReport(YearReport yearReport){

        reportDao.insertYearReport(yearReport);
        //将所有去年的月报的yearId登记为该年报
        reportDao.updateMonthReportYearId(yearReport.getId(),yearReport.getDate());
        //获取所有的部门统计
        List<DepartmentStatistic> departmentStatistics = reportDao.findAllDepartmentStatisticByYearReportId(yearReport.getId());
        //统计总和
        List<MonthReportStatistic> monthReportStatistics = departToMonth(departmentStatistics,yearReport.getId());
        //插入数据库
        if(monthReportStatistics.size()>0)
            reportDao.insertMonthReportStatistic(monthReportStatistics);
    }

    private List<TrainStatistic> projectToTrainStatistic(List<Project> projects,Integer monthReportId){
        List<TrainStatistic> statisticList = new ArrayList<>();
        for (Project project : projects) {
            TrainStatistic train = new TrainStatistic();
            train.setName(project.getName());
            train.setStartDate(project.getStartDate());
            train.setEndDate(project.getEndDate());
            train.setPeople(project.getPeople());
            UsageInfo info = usageMap.get(project.getUid());
            if(info == null){
                throw new ResourceException(ResultEnum.UNKNOWN_ERROR);
            }
            train.setClassroomUsage(info.classUsage);
            train.setDormitoryUsage(info.dormUsage);
            train.setProjectUid(project.getUid());
            train.setPart(project.getPart().getName());
            train.setMonthReportId(monthReportId);
            statisticList.add(train);
        }
        return statisticList;
    }

    private List<DepartmentStatistic> trainToDepart(List<TrainStatistic> list,Integer monthReportId){
        List<DepartmentStatistic> departList = new ArrayList<>();
        List<Part> partList = partService.findAllPart();
        DepartmentStatistic all = initAll(departList,monthReportId);
        for(Part part:partList){
            DepartmentStatistic depart = new DepartmentStatistic();
            depart.setPart(part.getName());
            depart.setMonthReportId(monthReportId);
            departList.add(depart);
        }
        for(DepartmentStatistic statistic:departList){//对每个部门
            for (TrainStatistic trainStatistic : list) {//对每个项目
                if(statistic.getPart().equals(trainStatistic.getPart())){
                    statistic.addProject(1);
                    statistic.addPeople(trainStatistic.getPeople());
                    statistic.addClassroomUsage(trainStatistic.getClassroomUsage());
                    statistic.addDormitoryUse(trainStatistic.getDormitoryUsage());
                }
            }
            all.addProject(statistic.getProject());
            all.addPeople(statistic.getPeople());
            all.addClassroomUsage(statistic.getClassroomUsage());
            all.addDormitoryUse(statistic.getDormitoryUsage());
        }
        return departList;
    }

    private List<MonthReportStatistic> departToMonth(List<DepartmentStatistic> departList,Integer yearReportId){
        List<MonthReportStatistic> monthReportStatisticList = new ArrayList<>();
        Map<String,DepartmentStatistic> map = new HashMap<>();
        for (DepartmentStatistic statistic : departList) {
            String part = statistic.getPart();
            if(map.containsKey(part)){
                DepartmentStatistic s = map.get(part);
                s.addProject(statistic.getProject());
                s.addPeople(statistic.getPeople());
                s.addDormitoryUse(statistic.getDormitoryUsage());
                s.addClassroomUsage(statistic.getClassroomUsage());
            }else{
                map.put(part,statistic);
            }
        }
        for (Map.Entry<String,DepartmentStatistic> entry : map.entrySet()) {
            MonthReportStatistic m = new MonthReportStatistic();
            m.setPart(entry.getKey());
            DepartmentStatistic depart = entry.getValue();
            m.setPeople(depart.getPeople());
            m.setProject(depart.getProject());
            m.setClassroomUsage(depart.getClassroomUsage());
            m.setDormitoryUsage(depart.getDormitoryUsage());
            m.setYearReportId(yearReportId);
            monthReportStatisticList.add(m);
        }
        return monthReportStatisticList;
    }

    private DepartmentStatistic initAll(List<DepartmentStatistic> departList,Integer monthReportId){
        DepartmentStatistic depart = new DepartmentStatistic();
        depart.setPart("所有部门（合计）");
        depart.setMonthReportId(monthReportId);
        departList.add(depart);
        return depart;
    }

    private void initUsageMap(List<Project> projectList){
        usageMap = new HashMap<>();
        List<AccCheck>  accChecks = checkDao.findAllAccCheck();
        List<ClassroomCheck> classroomChecks = checkDao.findAllClassroomCheck();
        for (Project project : projectList) {
            UsageInfo usageInfo = new UsageInfo();
            for (AccCheck accCheck : accChecks) {
                if(project.getUid().equals(accCheck.getProjectUid())){
                    usageInfo.dormUsage = accCheck.getUsage();
                }
            }
            for (ClassroomCheck classroomCheck : classroomChecks) {
                if(project.getUid().equals(classroomCheck.getProjectUid())){
                    usageInfo.classUsage = Integer.parseInt(classroomCheck.getUsage());
                }
            }
            usageMap.put(project.getUid(),usageInfo);
        }
    }

    static class UsageInfo{
        public Integer dormUsage = 0;
        public Integer classUsage = 0;
    }
}
